package com.baichuan.util;



import com.baichuan.entity.CmsRequestLog;
import com.baichuan.service.CmsRequestLogService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Date;


/**
 * @Auther: leo
 * @Date: 2020/04/10 12:52
 * @Description: Spring工具类
 */
@Slf4j
public class SpringUtil implements ApplicationContextAware, HandlerInterceptor {
    private static ApplicationContext applicationContext;
    private static ThreadLocal<HttpServletRequest> requestLocal = new ThreadLocal<>();

    @Autowired
    private CmsRequestLogService logService;

    @Autowired
    private RedisUtil redisUtil;

    @Override
    public void setApplicationContext(ApplicationContext context) {
        applicationContext = context;
    }

    /**
     * 获取applicationContext
     *
     * @return
     */
    private static ApplicationContext getApplicationContext() {
        if (null == applicationContext)
            log.error(">>>>>>>>>>>>>applicationContext is null in getApplicationContext");
        return applicationContext;
    }

    /**
     * 通过class获取Bean.
     *
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T getBean(Class<T> clazz) {
        try {
            return getApplicationContext().getBean(clazz);
        } catch (Exception e) {
            log.error("SpringUtil.getBean({}) error: {}", clazz, e.getMessage());
            throw e;
        }
    }

    /**
     * 获取request
     *
     * @return
     */
    public static HttpServletRequest getRequest() {
        HttpServletRequest request = requestLocal.get();
        if (null == request && RequestContextHolder.getRequestAttributes() != null)
            request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        if (null == request)
            log.error(">>>>>>>>>>>>>>request is null in getRequest!!!");
        return request;
    }

    private static void setRequest(HttpServletRequest request) {
        if (null == request) {
            log.error(">>>>>>>>>>>>>request is null in setRequest");
            return;
        }
        requestLocal.set(request);
    }

    /// 获取当前环境
    public static String getActiveProfile() {
        return applicationContext.getEnvironment().getActiveProfiles()[0];
    }

    /// 获取当前环境
    public static String getProfileProperty(String key) {
        return applicationContext.getEnvironment().getProperty(key);
    }

//    /**
//     * 在请求处理之前执行，主要用于权限验证、参数过滤等
//     *
//     * @param request
//     * @param response
//     * @param handler
//     * @return
//     * @throws Exception
//     */
//    @Override
//    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
//            throws Exception {
//        setRequest(request);
//        if (handler == null)
//            return true;
//        if (!(handler instanceof HandlerMethod))
//            return true;
//        if (!isCheckToken((HandlerMethod) handler)) {
//            return true;
//        }
//
//        RequestHeaderParams requestHeaderParams = RequestParamsUtil.getHeaderParams();
//        String token = requestHeaderParams.get_t();
//        if (StringUtils.isEmpty(token)) {
//            writerResult(request, response, ResponseResult.writeInvalid("token不能为空"));
//            return false;
//        }
//        /*if ("dev".equals(getActiveProfile()))
//            return true;*/
//        if (!CmsUserTokenUtil.isVerifyToken(token)) {
//            writerResult(request, response, ResponseResult.writeTokenError());
//            return false;
//        }
//
//        if (isCheckPermission((HandlerMethod) handler)) {
//            String uri = request.getRequestURI();
//            String prefix = getProfileProperty("server.servlet.context-path");
//            uri = uri.replace(prefix, "");
//            Map<String, String> sysPermissionMap = redisUtil.get(RedisKey.CMS_SYS_USER_PERMISSION_MAP + CmsUserTokenUtil.getUserId(token));
//            if (sysPermissionMap == null) {
//                writerResult(request, response, ResponseResult.writePermissionError());
//                return false;
//            }
//
//            if (sysPermissionMap.get(uri) == null) {
//                writerResult(request, response, ResponseResult.writePermissionError());
//                return false;
//            }
//        }
//        return true;
//    }
//
//    /**
//     * 是否需要校验token
//     *
//     * @param handlerMethod
//     * @return
//     */
//    private boolean isCheckToken(HandlerMethod handlerMethod) {
//        Object bean = handlerMethod.getBean();
//        if (null == bean)
//            return false;
//        Class beanClass = AopUtils.getTargetClass(bean);
//        return !(!beanClass.isAnnotationPresent(RestController.class) && !beanClass.isAnnotationPresent(Controller.class)) && !beanClass.isAnnotationPresent(IgnoreCheckToken.class) && !handlerMethod.hasMethodAnnotation(IgnoreCheckToken.class);
//    }
//
//    /**
//     * 是否需要校验token
//     *
//     * @param handlerMethod
//     * @return
//     */
//    private boolean isCheckPermission(HandlerMethod handlerMethod) {
//        Object bean = handlerMethod.getBean();
//        if (null == bean)
//            return false;
//        Class beanClass = AopUtils.getTargetClass(bean);
//        return !(!beanClass.isAnnotationPresent(RestController.class) && !beanClass.isAnnotationPresent(Controller.class)) && !beanClass.isAnnotationPresent(IgnoreCheckPermission.class) && !handlerMethod.hasMethodAnnotation(IgnoreCheckPermission.class);
//    }
//
//    /**
//     * 是否需要校验是否车商用户
//     *
//     * @param handlerMethod
//     * @return
//     */
//    private boolean isCheckDealerUser(HandlerMethod handlerMethod) {
//        Object bean = handlerMethod.getBean();
//        if (null == bean)
//            return false;
//        Class beanClass = AopUtils.getTargetClass(bean);
//        return !(!beanClass.isAnnotationPresent(RestController.class) && !beanClass.isAnnotationPresent(Controller.class)) && !beanClass.isAnnotationPresent(IgnoreCheckDealerUser.class) && !handlerMethod.hasMethodAnnotation(IgnoreCheckDealerUser.class);
//    }

    /**
     * 写无效token
     *
     * @param response
     * @return
     * @throws Exception
     */
    private void writerResult(HttpServletRequest request, HttpServletResponse response, String content) throws Exception {
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json; charset=utf-8");
        PrintWriter out = null;
        try {
            out = response.getWriter();
            out.append(content);
        } catch (Exception e) {
            log.error("writerResultException", e);
            response.sendError(500);
        } finally {
            out.close();
        }
        addLog(request, content);
    }

    private void addLog(HttpServletRequest request, String result) {
        try {

            BufferedReader br = null;
            try {
                br = new BufferedReader(new InputStreamReader(request.getInputStream(), "UTF-8"));
            } catch (IOException e) {
                e.printStackTrace();
            }
            String line = null;
            StringBuilder sb = new StringBuilder();
            try {
                while ((line = br.readLine()) != null) {
                    sb.append(line);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            String args = sb.toString();
            if (StringUtils.isNotEmpty(args) && args.length() > 2000) {
                args = args.substring(0, 2000);
            }
            String uri = request.getRequestURI();
            CmsRequestLog log = new CmsRequestLog();
            Integer userId = RequestParamsUtil.getSysUserId();
            if (userId != null)
                log.setUserId(userId + "");
            log.setIpAddress(IpAddressUtil.getIpAddress(request));
            if (StringUtils.isNotEmpty(args) && args.length() > 3000) {
                args = args.substring(0, 3000);
            }
            log.setUri(uri);
            //上传图片不记录上传参数
            log.setArgs(args);
            log.setTimes(0);
            log.setCreateTime(new Date());
            if (StringUtils.isNotEmpty(result) && result.length() > 3000) {
                result = result.substring(0, 3000);
            }
            log.setResponseContent(result);
            //logService.addLog(log);
        } catch (Exception e) {
            log.error("addLog", e);
        }
    }
}
